import 'package:flutter/material.dart';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';
import 'package:file_picker/file_picker.dart';
import 'asr_ffi.dart';
import 'test_logging.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ASR ONNX FFI Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ASRHomePage(title: 'ASR ONNX OFFLINE 示例'),
    );
  }
}

class ASRHomePage extends StatefulWidget {
  const ASRHomePage({super.key, required this.title});

  final String title;

  @override
  State<ASRHomePage> createState() => _ASRHomePageState();
}

class _ASRHomePageState extends State<ASRHomePage> {
  String _recognitionResult = '点击按钮开始语音识别';
  bool _isProcessing = false;
  String? _selectedAudioFile; // 选择的音频文件路径
  final List<String> _audioAssets = [
    'assets/audios/asr_example_zh.wav',
    'assets/audios/vad_example.wav',
  ];

  @override
  void initState() {
    super.initState();
    AsrFFI.initialize();
  }

  Future<String> _copyAssetToTemp(String asset) async {
    final dir = await getTemporaryDirectory();
    final outPath = path.join(dir.path, path.basename(asset));
    final out = File(outPath);
    if (!await out.exists()) {
      final data = await rootBundle.load(asset);
      await out.writeAsBytes(data.buffer.asUint8List());
    }
    return outPath;
  }

  /// 选择音频文件
  Future<void> _selectAudioFile() async {
    try {
      FilePickerResult? result = await FilePicker.platform.pickFiles(
        type: FileType.custom,
        allowedExtensions: ['wav', 'mp3', 'flac', 'm4a', 'aac', 'ogg'],
        dialogTitle: '选择音频文件',
      );

      if (result != null && result.files.single.path != null) {
        final selectedPath = result.files.single.path!;
        final fileInfo = AsrFFI.getAudioFileInfo(selectedPath);

        if (!fileInfo['isSupported']) {
          setState(() {
            _recognitionResult = '不支持的音频格式: ${fileInfo['extension']}';
          });
          return;
        }

        setState(() {
          _selectedAudioFile = selectedPath;
          _recognitionResult =
              '已选择文件: ${fileInfo['name']}\n'
              '大小: ${fileInfo['sizeString']}\n'
              '格式: ${fileInfo['extension']}';
        });
      }
    } catch (e) {
      setState(() {
        _recognitionResult = '选择文件失败: $e';
      });
    }
  }

  /// 使用选择的文件进行离线识别
  Future<void> _runOfflineWithSelectedFile() async {
    if (_selectedAudioFile == null) {
      setState(() {
        _recognitionResult = '请先选择音频文件';
      });
      return;
    }

    // 再次验证文件
    final fileInfo = AsrFFI.getAudioFileInfo(_selectedAudioFile!);
    if (!fileInfo['exists']) {
      setState(() {
        _recognitionResult = '选择的文件不存在，请重新选择';
        _selectedAudioFile = null;
      });
      return;
    }

    setState(() {
      _isProcessing = true;
      _recognitionResult = '正在离线识别: ${fileInfo['name']}...';
    });

    try {
      final text = await AsrFFI.performOfflineRecognition(_selectedAudioFile!);
      setState(() {
        _recognitionResult = '离线识别结果:\n$text';
      });
    } catch (e) {
      setState(() {
        _recognitionResult = '离线识别失败: $e';
      });
    } finally {
      setState(() {
        _isProcessing = false;
      });
    }
  }

  /// 使用选择的文件进行在线识别
  Future<void> _runOnlineWithSelectedFile() async {
    if (_selectedAudioFile == null) {
      setState(() {
        _recognitionResult = '请先选择音频文件';
      });
      return;
    }

    // 再次验证文件
    final fileInfo = AsrFFI.getAudioFileInfo(_selectedAudioFile!);
    if (!fileInfo['exists']) {
      setState(() {
        _recognitionResult = '选择的文件不存在，请重新选择';
        _selectedAudioFile = null;
      });
      return;
    }

    setState(() {
      _isProcessing = true;
      _recognitionResult = '正在在线识别: ${fileInfo['name']}...';
    });

    try {
      final text = await AsrFFI.performOnlineRecognition(_selectedAudioFile!);
      setState(() {
        _recognitionResult = '在线识别结果:\n$text';
      });
    } catch (e) {
      setState(() {
        _recognitionResult = '在线识别失败: $e';
      });
    } finally {
      setState(() {
        _isProcessing = false;
      });
    }
  }

  Future<void> _runOffline(String asset) async {
    setState(() {
      _isProcessing = true;
      _recognitionResult = '离线识别中...';
    });
    try {
      final wavPath = await _copyAssetToTemp(asset);
      final text = await AsrFFI.performOfflineRecognition(wavPath);
      setState(() {
        _recognitionResult = text;
      });
    } catch (e) {
      setState(() {
        _recognitionResult = '失败: $e';
      });
    } finally {
      setState(() {
        _isProcessing = false;
      });
    }
  }

  Future<void> _runOnline(String asset) async {
    setState(() {
      _isProcessing = true;
      _recognitionResult = '在线识别（文件流式）中...';
    });
    try {
      final wavPath = await _copyAssetToTemp(asset);
      final text = await AsrFFI.performOfflineRecognition(wavPath);
      setState(() {
        _recognitionResult = text;
      });
    } catch (e) {
      setState(() {
        _recognitionResult = '失败: $e';
      });
    } finally {
      setState(() {
        _isProcessing = false;
      });
    }
  }

  Future<void> _showDiagnostic() async {
    try {
      final diagnosticInfo = await AsrFFI.getDeploymentDiagnostic();

      if (!mounted) return;

      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('部署诊断信息'),
            content: SizedBox(
              width: double.maxFinite,
              child: SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    _buildDiagnosticSection('平台信息', diagnosticInfo['platform']),
                    const SizedBox(height: 16),
                    _buildDiagnosticSection(
                      '目录结构',
                      diagnosticInfo['directories'],
                    ),
                    const SizedBox(height: 16),
                    _buildDiagnosticSection(
                      '可执行文件',
                      diagnosticInfo['executables'],
                    ),
                    const SizedBox(height: 16),
                    _buildDiagnosticSection('DLL文件', diagnosticInfo['dlls']),
                    const SizedBox(height: 16),
                    _buildDiagnosticSection('模型文件', diagnosticInfo['models']),
                  ],
                ),
              ),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('关闭'),
              ),
            ],
          );
        },
      );
    } catch (e) {
      if (!mounted) return;

      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('错误'),
            content: Text('获取诊断信息失败: $e'),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('确定'),
              ),
            ],
          );
        },
      );
    }
  }

  /// 打开日志测试页面
  void _openLogTestPage() {
    Navigator.of(
      context,
    ).push(MaterialPageRoute(builder: (context) => const TestLoggingPage()));
  }

  /// 显示日志弹窗
  Future<void> _showLogDialog() async {
    try {
      // 获取日志文件路径
      final logPath = AsrFFI.getLogFilePath();

      if (logPath == null) {
        _showErrorDialog('日志文件未初始化', '请先进行一次语音识别操作来创建日志文件。');
        return;
      }

      // 检查日志文件是否存在
      final logFile = File(logPath);
      if (!logFile.existsSync()) {
        _showErrorDialog('日志文件不存在', '日志文件路径: $logPath\n\n请先进行一次语音识别操作来创建日志文件。');
        return;
      }

      // 显示加载指示器
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => const Center(child: CircularProgressIndicator()),
      );

      // 读取日志内容
      final logContent = await AsrFFI.getLogFileContent();

      // 关闭加载指示器
      if (mounted) Navigator.of(context).pop();

      // 显示日志内容弹窗
      if (mounted) {
        showDialog(
          context: context,
          builder: (context) => _buildLogDialog(logPath, logContent),
        );
      }
    } catch (e) {
      // 关闭可能的加载指示器
      if (mounted) Navigator.of(context).pop();

      _showErrorDialog('读取日志失败', '错误详情: $e');
    }
  }

  /// 构建日志显示弹窗
  Widget _buildLogDialog(String logPath, String logContent) {
    return Dialog(
      child: Container(
        width: MediaQuery.of(context).size.width * 0.8,
        height: MediaQuery.of(context).size.height * 0.8,
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 标题栏
            Row(
              children: [
                const Icon(Icons.article, color: Colors.teal),
                const SizedBox(width: 8),
                const Expanded(
                  child: Text(
                    'ASR 运行日志',
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                  ),
                ),
                IconButton(
                  onPressed: () => Navigator.of(context).pop(),
                  icon: const Icon(Icons.close),
                ),
              ],
            ),
            const Divider(),

            // 日志文件信息
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey.shade100,
                borderRadius: BorderRadius.circular(8),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      const Icon(Icons.folder, size: 16, color: Colors.grey),
                      const SizedBox(width: 4),
                      Expanded(
                        child: Text(
                          '文件路径: $logPath',
                          style: const TextStyle(fontSize: 12),
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 4),
                  Row(
                    children: [
                      const Icon(Icons.info, size: 16, color: Colors.grey),
                      const SizedBox(width: 4),
                      Text(
                        '文件大小: ${_formatLogFileSize(logContent)}',
                        style: const TextStyle(fontSize: 12),
                      ),
                      const Spacer(),
                      Text(
                        '更新时间: ${_getFileLastModified(logPath)}',
                        style: const TextStyle(fontSize: 12),
                      ),
                    ],
                  ),
                ],
              ),
            ),
            const SizedBox(height: 16),

            // 日志内容
            const Text(
              '日志内容:',
              style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Expanded(
              child: Container(
                width: double.infinity,
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey.shade300),
                  borderRadius: BorderRadius.circular(8),
                  color: Colors.grey.shade50,
                ),
                child: SingleChildScrollView(
                  child: SelectableText(
                    logContent.isEmpty ? '日志内容为空' : logContent,
                    style: const TextStyle(
                      fontFamily: 'monospace',
                      fontSize: 12,
                    ),
                  ),
                ),
              ),
            ),

            const SizedBox(height: 16),

            // 操作按钮
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                TextButton.icon(
                  onPressed: () async {
                    try {
                      await AsrFFI.openLogFileFolder();
                      if (mounted) {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text('已打开日志文件夹'),
                            backgroundColor: Colors.green,
                          ),
                        );
                      }
                    } catch (e) {
                      _showErrorDialog('打开文件夹失败', '$e');
                    }
                  },
                  icon: const Icon(Icons.folder_open),
                  label: const Text('打开文件夹'),
                ),
                const SizedBox(width: 8),
                TextButton.icon(
                  onPressed: () async {
                    // 刷新日志内容
                    Navigator.of(context).pop();
                    await _showLogDialog();
                  },
                  icon: const Icon(Icons.refresh),
                  label: const Text('刷新'),
                ),
                const SizedBox(width: 8),
                ElevatedButton(
                  onPressed: () => Navigator.of(context).pop(),
                  child: const Text('关闭'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  /// 格式化日志文件大小
  String _formatLogFileSize(String content) {
    final bytes = content.length;
    if (bytes < 1024) return '$bytes 字符';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
  }

  /// 获取文件最后修改时间
  String _getFileLastModified(String filePath) {
    try {
      final file = File(filePath);
      if (file.existsSync()) {
        final lastModified = file.lastModifiedSync();
        return '${lastModified.year}-${lastModified.month.toString().padLeft(2, '0')}-${lastModified.day.toString().padLeft(2, '0')} ${lastModified.hour.toString().padLeft(2, '0')}:${lastModified.minute.toString().padLeft(2, '0')}';
      }
    } catch (e) {
      // 忽略错误
    }
    return '未知';
  }

  /// 显示错误对话框
  void _showErrorDialog(String title, String message) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Row(
          children: [
            const Icon(Icons.error, color: Colors.red),
            const SizedBox(width: 8),
            Text(title),
          ],
        ),
        content: Text(message),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('确定'),
          ),
        ],
      ),
    );
  }

  Future<void> _checkSystemDependencies() async {
    try {
      final dependencies = await AsrFFI.checkSystemDependencies();

      if (!mounted) return;

      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('系统依赖检查'),
            content: SizedBox(
              width: double.maxFinite,
              child: SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    _buildDependencySection(
                      'Visual C++ Redistributable',
                      dependencies['vcredist'],
                    ),
                    const SizedBox(height: 16),
                    _buildDependencySection(
                      '.NET Runtime',
                      dependencies['dotnet'],
                    ),
                    const SizedBox(height: 16),
                    _buildDependencySection(
                      'Windows版本',
                      dependencies['windows'],
                    ),
                    const SizedBox(height: 20),
                    _buildRecommendations(dependencies),
                  ],
                ),
              ),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('关闭'),
              ),
              if (_needsVCRedist(dependencies))
                ElevatedButton(
                  onPressed: () => _openVCRedistDownload(),
                  child: const Text('下载 VC++ Redistributable'),
                ),
            ],
          );
        },
      );
    } catch (e) {
      if (!mounted) return;

      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('错误'),
            content: Text('检查系统依赖失败: $e'),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('确定'),
              ),
            ],
          );
        },
      );
    }
  }

  Widget _buildDependencySection(String title, dynamic data) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          title,
          style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
        ),
        const SizedBox(height: 8),
        Container(
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: _getDependencyColor(data),
            borderRadius: BorderRadius.circular(8),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  Icon(
                    _getDependencyIcon(data),
                    color: _getDependencyIconColor(data),
                    size: 20,
                  ),
                  const SizedBox(width: 8),
                  Text(
                    _getDependencyStatus(data),
                    style: TextStyle(
                      fontWeight: FontWeight.w500,
                      color: _getDependencyIconColor(data),
                    ),
                  ),
                ],
              ),
              if (data is Map && data['details'] != null) ...[
                const SizedBox(height: 8),
                Text(
                  _formatDependencyDetails(data['details']),
                  style: const TextStyle(fontSize: 12),
                ),
              ],
              if (data is Map && data['error'] != null) ...[
                const SizedBox(height: 8),
                Text(
                  '错误: ${data['error']}',
                  style: const TextStyle(fontSize: 12, color: Colors.red),
                ),
              ],
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildRecommendations(Map<String, dynamic> dependencies) {
    final recommendations = <String>[];

    if (_needsVCRedist(dependencies)) {
      recommendations.add(
        '• 安装 Microsoft Visual C++ Redistributable 2015-2022 (x64)',
      );
    }

    if (dependencies['dotnet'] != null &&
        dependencies['dotnet']['installed'] == false) {
      recommendations.add('• 考虑安装 .NET Runtime (可选)');
    }

    if (recommendations.isEmpty) {
      recommendations.add('• 所有依赖项检查通过！');
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          '建议',
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
        ),
        const SizedBox(height: 8),
        Container(
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: Colors.yellow.shade50,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(color: Colors.orange.shade200),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: recommendations
                .map(
                  (rec) => Padding(
                    padding: const EdgeInsets.symmetric(vertical: 2),
                    child: Text(rec),
                  ),
                )
                .toList(),
          ),
        ),
      ],
    );
  }

  Color _getDependencyColor(dynamic data) {
    if (data is Map) {
      if (data['installed'] == true) {
        return Colors.green.shade50;
      } else if (data['installed'] == false) {
        return Colors.red.shade50;
      }
    }
    return Colors.grey.shade50;
  }

  IconData _getDependencyIcon(dynamic data) {
    if (data is Map) {
      if (data['installed'] == true) {
        return Icons.check_circle;
      } else if (data['installed'] == false) {
        return Icons.error;
      }
    }
    return Icons.help;
  }

  Color _getDependencyIconColor(dynamic data) {
    if (data is Map) {
      if (data['installed'] == true) {
        return Colors.green;
      } else if (data['installed'] == false) {
        return Colors.red;
      }
    }
    return Colors.grey;
  }

  String _getDependencyStatus(dynamic data) {
    if (data is Map) {
      if (data['installed'] == true) {
        return '已安装';
      } else if (data['installed'] == false) {
        return '未安装';
      }
    }
    return '未知';
  }

  String _formatDependencyDetails(dynamic details) {
    if (details is String) {
      // 简化注册表输出
      if (details.contains('Version')) {
        final lines = details.split('\n');
        for (final line in lines) {
          if (line.contains('Version') && line.contains('REG_SZ')) {
            final parts = line.split('REG_SZ');
            if (parts.length > 1) {
              return '版本: ${parts[1].trim()}';
            }
          }
        }
      }
      return details.length > 100 ? '${details.substring(0, 100)}...' : details;
    }
    return details.toString();
  }

  bool _needsVCRedist(Map<String, dynamic> dependencies) {
    return dependencies['vcredist'] != null &&
        dependencies['vcredist']['installed'] == false;
  }

  void _openVCRedistDownload() {
    // 这里可以打开浏览器到Microsoft官方下载页面
    // 由于这是演示，我们显示一个信息对话框
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('下载 Visual C++ Redistributable'),
          content: const Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('请访问Microsoft官方网站下载:'),
              SizedBox(height: 8),
              SelectableText(
                'https://aka.ms/vs/17/release/vc_redist.x64.exe',
                style: TextStyle(
                  color: Colors.blue,
                  decoration: TextDecoration.underline,
                ),
              ),
              SizedBox(height: 16),
              Text('或者搜索: "Microsoft Visual C++ Redistributable 2022 x64"'),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('确定'),
            ),
          ],
        );
      },
    );
  }

  Widget _buildDiagnosticSection(String title, dynamic data) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          title,
          style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
        ),
        const SizedBox(height: 8),
        Container(
          padding: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            color: Colors.grey.shade100,
            borderRadius: BorderRadius.circular(4),
          ),
          child: Text(
            _formatDiagnosticData(data),
            style: const TextStyle(fontFamily: 'monospace', fontSize: 12),
          ),
        ),
      ],
    );
  }

  String _formatDiagnosticData(dynamic data) {
    if (data is Map) {
      final buffer = StringBuffer();
      data.forEach((key, value) {
        if (value is Map || value is List) {
          buffer.writeln('$key:');
          final subData = _formatDiagnosticData(value);
          for (final line in subData.split('\n')) {
            if (line.isNotEmpty) {
              buffer.writeln('  $line');
            }
          }
        } else {
          buffer.writeln('$key: $value');
        }
      });
      return buffer.toString();
    } else if (data is List) {
      return data.map((item) => '- $item').join('\n');
    } else {
      return data.toString();
    }
  }

  Future<void> _forceReExtractAssets() async {
    try {
      // 显示确认对话框
      final shouldProceed = await showDialog<bool>(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('确认操作'),
            content: const Text(
              '这将强制重新提取所有资源文件，可能需要一些时间。\n'
              '这通常用于解决DLL依赖问题。\n\n'
              '是否继续？',
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(false),
                child: const Text('取消'),
              ),
              TextButton(
                onPressed: () => Navigator.of(context).pop(true),
                style: TextButton.styleFrom(foregroundColor: Colors.red),
                child: const Text('确定'),
              ),
            ],
          );
        },
      );

      if (shouldProceed != true) return;

      // 显示进度对话框
      if (!mounted) return;
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return const AlertDialog(
            title: Text('重新提取资源'),
            content: Row(
              children: [
                CircularProgressIndicator(),
                SizedBox(width: 16),
                Text('正在重新提取所有资源文件...'),
              ],
            ),
          );
        },
      );

      // 执行强制重新提取
      await AsrFFI.forceReExtractAssets();

      if (!mounted) return;
      Navigator.of(context).pop(); // 关闭进度对话框

      // 显示成功对话框
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('提取完成'),
            content: const Text(
              '资源文件已重新提取完成！\n'
              '现在可以重试语音识别功能。',
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('确定'),
              ),
            ],
          );
        },
      );
    } catch (e) {
      if (!mounted) return;
      Navigator.of(context).pop(); // 确保关闭进度对话框

      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('错误'),
            content: Text('重新提取资源失败: $e'),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('确定'),
              ),
            ],
          );
        },
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('识别结果:'),
            Padding(
              padding: const EdgeInsets.all(12.0),
              child: Text(_recognitionResult),
            ),
            const SizedBox(height: 16),

            // 文件选择区域
            Container(
              padding: const EdgeInsets.all(16),
              margin: const EdgeInsets.symmetric(horizontal: 20),
              decoration: BoxDecoration(
                color: Colors.blue.shade50,
                borderRadius: BorderRadius.circular(12),
                border: Border.all(color: Colors.blue.shade200),
              ),
              child: Column(
                children: [
                  const Text(
                    '自定义音频文件',
                    style: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                      color: Colors.blue,
                    ),
                  ),
                  const SizedBox(height: 12),
                  ElevatedButton.icon(
                    onPressed: _isProcessing ? null : _selectAudioFile,
                    icon: const Icon(Icons.folder_open),
                    label: const Text('选择音频文件'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue.shade100,
                      foregroundColor: Colors.blue.shade800,
                    ),
                  ),
                  if (_selectedAudioFile != null) ...[
                    const SizedBox(height: 8),
                    Text(
                      '已选择: ${path.basename(_selectedAudioFile!)}',
                      style: TextStyle(
                        color: Colors.green.shade700,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                    const SizedBox(height: 12),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        ElevatedButton.icon(
                          onPressed: _isProcessing
                              ? null
                              : _runOfflineWithSelectedFile,
                          icon: const Icon(Icons.hearing),
                          label: const Text('离线识别'),
                          style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.green.shade100,
                            foregroundColor: Colors.green.shade800,
                          ),
                        ),
                        ElevatedButton.icon(
                          onPressed: _isProcessing
                              ? null
                              : _runOnlineWithSelectedFile,
                          icon: const Icon(Icons.surround_sound),
                          label: const Text('在线识别'),
                          style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.purple.shade100,
                            foregroundColor: Colors.purple.shade800,
                          ),
                        ),
                      ],
                    ),
                  ],
                ],
              ),
            ),

            const SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                Column(
                  children: [
                    const Text(
                      '离线识别',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                    for (final a in _audioAssets)
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 3),
                        child: ElevatedButton(
                          onPressed: _isProcessing
                              ? null
                              : () => _runOffline(a),
                          style: ElevatedButton.styleFrom(
                            textStyle: const TextStyle(fontSize: 12),
                          ),
                          child: Text(path.basename(a).replaceAll('.wav', '')),
                        ),
                      ),
                  ],
                ),
                Column(
                  children: [
                    const Text(
                      '在线识别',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                    for (final a in _audioAssets)
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 3),
                        child: ElevatedButton(
                          onPressed: _isProcessing ? null : () => _runOnline(a),
                          style: ElevatedButton.styleFrom(
                            textStyle: const TextStyle(fontSize: 12),
                          ),
                          child: Text(path.basename(a).replaceAll('.wav', '')),
                        ),
                      ),
                  ],
                ),
              ],
            ),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: _showDiagnostic,
              icon: const Icon(Icons.info_outline),
              label: const Text('显示部署诊断信息'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.blue.shade100,
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _checkSystemDependencies,
              icon: const Icon(Icons.build_circle_outlined),
              label: const Text('检查系统依赖'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.orange.shade100,
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _openLogTestPage,
              icon: const Icon(Icons.description),
              label: const Text('日志测试页面'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.green.shade100,
                foregroundColor: Colors.green.shade800,
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _showLogDialog,
              icon: const Icon(Icons.article),
              label: const Text('查看日志'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.teal.shade100,
                foregroundColor: Colors.teal.shade800,
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _forceReExtractAssets,
              icon: const Icon(Icons.refresh),
              label: const Text('强制重新提取资源'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.red.shade100,
                foregroundColor: Colors.red.shade800,
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          FloatingActionButton(
            heroTag: 'offline',
            onPressed: _isProcessing
                ? null
                : () => _runOffline(_audioAssets.first),
            tooltip: _isProcessing ? '识别中' : '离线开始',
            child: _isProcessing
                ? const CircularProgressIndicator()
                : const Icon(Icons.hearing),
          ),
          const SizedBox(height: 10),
          FloatingActionButton(
            heroTag: 'online',
            onPressed: _isProcessing
                ? null
                : () => _runOnline(_audioAssets.first),
            tooltip: _isProcessing ? '识别中' : '在线开始',
            child: _isProcessing
                ? const CircularProgressIndicator()
                : const Icon(Icons.surround_sound),
          ),
        ],
      ),
    );
  }
}
